#pragma once
#include "DJoint.h"

namespace Skill
{
	namespace Ode
	{
		ref class DWorld;
		ref class DVector3;
		namespace Joints
		{
			ref class DJointGroup;
			public ref class DHinge : DJoint
			{
			protected:
				virtual void CollectManagedMemory() override;
			public:				
				///<summary>
				/// Create a new joint of the hinge type.
				///</summary>
				///<param name = "world"> Wrold </param>
				///<param name = "group">
				/// set to null to allocate the joint normally.
				/// If it is valid the joint is allocated in the given joint group.
				///</param>				
				DHinge(DWorld^ world , DJointGroup^ group);	

				///<summary>
				/// Gets or set hinge anchor parameter in world coordinates.
				///
				/// This returns the point on body 1. If the joint is perfectly satisfied,
				/// this will be the same as the point on body 2.
				///</summary>
				REF_PROP_DECLARATION_GETSET(DVector3,Anchor1);

				void SetAnchorDelta(dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
				void SetAnchorDelta(DVector3^ p, DVector3^ a);				
				///<summary>
				/// Gets or set hinge axis.
				///</summary>
				REF_PROP_DECLARATION_GETSET(DVector3,Axis);

				///<summary>
				/// Set the Hinge axis as if the 2 bodies were already at angle appart.				
				///
				/// This function initialize the Axis and the relative orientation of each body
				/// as if body1 was rotated around the axis by the angle value. \br
				///</summary>
				///<example>				
				/// Axis = new DVector3(1, 0, 0);
				/// If you request the position you will have: Angle == 0
				/// SetAxisDelta(1, 0, 0, 0.23);
				/// If you request the position you will have: Angle == 0.23
				///</example>				
				///<param name = "x"> The X component of the axis in world frame </param>
				///<param name = "y"> The Y component of the axis in world frame </param>
				///<param name = "z"> The Z component of the axis in world frame </param>
				///<param name = "angle">
				/// angle The angle for the offset of the relative orientation.
				/// As if body1 was rotated by angle when the Axis was set (see below).
				/// The rotation is around the new Hinge axis.
				///</param>
				///<remarks>
				/// Usually the function dJointSetHingeAxis set the current position of body1
				/// and body2 as the zero angle position. This function set the current position
				/// as the if the 2 bodies where \b angle appart.
				/// warning : Calling dJointSetHingeAnchor or dJointSetHingeAxis will reset the "zero"
				/// angle position.
				///</remarks>
				void SetAxisOffset(dReal x, dReal y, dReal z, dReal angle);				

				///<summary>
				/// set joint parameter
				///</summary>
				void SetParam(DJointParameters parameter, dReal value);	

				///<summary>
				/// Get joint parameter
				///</summary>
				dReal GetParam(DJointParameters parameter);

				///<summary>
				/// Applies the torque about the hinge axis.
				///
				/// That is, it applies a torque with specified magnitude in the direction
				/// of the hinge axis, to body 1, and with the same magnitude but in opposite
				/// direction to body 2. This function is just a wrapper for dBodyAddTorque()}
				///</summary>
				void AddTorque(dReal torque);				

				///<summary>
				/// Get the joint anchor point, in world coordinates.
				///</summary>
				///<returns>
				/// The point on body 2. If the joint is perfectly satisfied,
				/// this will return the same value as Anchor1.
				/// If not, this value will be slightly different.
				/// This can be used, for example, to see how far the joint has come apart.				
				///</returns>
				REF_PROP_DECLARATION_GET(DVector3,Anchor2);

				///<summary>
				/// Get the hinge angle.
				///
				/// The angle is measured between the two bodies, or between the body and
				/// the static environment.
				/// The angle will be between -pi..pi.
				/// Give the relative rotation with respect to the Hinge axis of Body 1 with
				/// respect to Body 2.
				/// When the hinge anchor or axis is set, the current position of the attached
				/// bodies is examined and that position will be the zero angle.
				///</summary>
				VALUE_PROP_DECLARATION_GET(dReal,Angle);

				///<summary>
				/// Get the hinge angle time derivative.
				///</summary>
				VALUE_PROP_DECLARATION_GET(dReal,AngleRate);
			};
		}
	}
}